LOADING...

loading

CSS Motion Path技术研究

最近在看css3手册时忽然发现了新的动画属性css, 名叫Motion Path,利用Motion Path,我们可以控制元素按照特定的路径进行位置变换的动画。并且,这个路径可以是非常复杂的一条路径。

CSS Motion Path 规范主要包含以下几个属性:

  • offset-path:接收一个 SVG 路径(与 SVG 的path、CSS 中的 clip-path 类似),指定运动的几何路径
  • offset-distance:控制当前元素基于 offset-path 运动的距离
  • offset-position:指定 offset-path 的初始位置
  • offset-anchor:定义沿 offset-path 定位的元素的锚点。 这个也算好理解,运动的元素可能不是一个点,那么就需要指定元素中的哪个点附着在路径上进行运动
  • offset-rotate:定义沿 offset-path 定位时元素的方向,说人话就是运动过程中元素的角度朝向

CSS Motion Path 实现直线路径动画

<div></div>
 
div {
   width: 60px;
   height: 60px;
   background: linear-gradient(#fc0, #f0c);
   offset-path: path("M 0 0 L 100 100");
   offset-rotate: 0deg;
   animation: move 2000ms infinite alternate ease-in-out;
}

@keyframes move {
  0% {
    offset-distance: 0%;
  }
  100% {
    offset-distance: 100%;
  }
}

offset-path 接收一个 SVG 的 path 路径,这里我们的路径内容是一条自定义路径 path(“M 0 0 L 100 100”),翻译过来就是从 0 0 点运动到 100px 100px 点。
我们会得到如下结果:
图片

通过控制元素的 offset-distance 从 0% 变化到 100% 进行元素的路径动画。
当然,上述的动画是最基本的,我可以充分利用 path 的特性,增加多个中间关键帧,稍微改造下上述代码:

<div></div>
 
div {
  /*
   * 只更改offset-path
   */
  offset-path: path("M 0 0 L 100 0 L 200 0 L 300 100 L 400 0 L 500 100 L 600 0 L 700 100 L 800 0");
}

这里最主要还是运用了 path 中的 L 指令,得到了如下图这样一条直线路径:
图片

CSS Motion Path 实现曲线路径动画

上面的运动轨迹都是由直线构成,下面我们看看如何使用 CSS Motion Path 实现曲线路径动画。

其实原理还是一模一样,只需要在 offset-path: path() 中添加曲线相关的路径即可。

在 SVG 的 Path 中,我们取其中一种绘制曲线的方法 – 贝塞尔曲线,譬如下述这条 path,其中的 path 为 d=”M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80”:

<svg width="400" height="160" xmlns="http://www.w3.org/2000/svg">
  <path d="M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80" stroke="black" fill="transparent"/>
</svg>

对应这样一条连续的贝塞尔曲线:
图片

将对应的路径应用在 offset-path: path 中:

<div></div>

div {
  width: 40px;
  height: 40px;
  background: linear-gradient(#fc0, #f0c);
  offset-path: path('M 10 80 C 80 10, 130 10, 190 80 S 300 150, 360 80');
  offset-rotate: 0deg;
  animation: move 3000ms infinite alternate linear;
  offset-rotate: unset;
}
 
@keyframes move {
  0% {
    offset-distance: 0%;
  }
 
  100% {
    offset-distance: 100%;
  }
}

可以得到如下运动效果:
图片

可以看到,元素是沿着贝塞尔曲线的路径进行运动的,并且,由于这次没有限制死 offset-rotate,元素的朝向也是跟随路径的朝向一直变化的。(可以联想成开车的时候,车头一直跟随道路会进行变化的,带动整个车身的角度变化)